import { initFullLayer } from '../../utils/LayerUtil';
import ITool from '../ITool';

/**
 * 选择工具箱
 * @implements {ITool}
 */
class SelectTool extends ITool {
  constructor(_top, _impl) {
    super(_top, _impl);
    this.name = 'SelectTool';
    this.desc = '选择工具箱';
    this.layeridPrefix = 'SelectTool';
    // 点
    this._pointClickHandler = this.pointClickHandler.bind(this);
    // 圆
    this._circleClickHandler = this.circleClickHandler.bind(this);
    this._circleMoveHandler = this.circleMoveHandler.bind(this);
    // 矩形
    this._rectClickHandler = this.rectClickHandler.bind(this);
    this._rectMoveHandler = this.rectMoveHandler.bind(this);
    // 多边形
    this._polygonClickHandler = this.polygonClickHandler.bind(this);
    this._polygonMoveHandler = this.polygonMoveHandler.bind(this);
    this._polygonDblclickHandler = this.polygonDblclickHandler.bind(this);
    // 选择完成回调函数
    this.callback = () => { };
  }

  onAdd() {
    super.onAdd();
    initFullLayer(this);
  }

  onRemove() {
    super.onRemove();
  }

  /**
   * 开始选择
   * @param {String} type 选择类型
   * @param {Function} callback 选择完成回调函数
   */
  active(type, callback) {
    if (callback) {
      this.callback = callback;
    }
    var _type = type || 'point';
    this.selectType = _type;
    switch (_type) {
      case 'point':
        this.pointSelect();
        break;
      case 'circle':
        this.circleSelect();
        break;
      case 'rect':
        this.rectSelect();
        break;
      case 'polygon':
        this.polygonSelect();
        break;
      default:
        this.log('unknown type ' + _type);
        break;
    }
    this.getUtil('CursorUtil').changeCursor('crosshair');
  }

  /**
   * 点选择
   * @ignore
   */
  pointSelect() {
    this.clear();
    this.getMap().on('click', this._pointClickHandler);
  }

  /**
   * 圆形选择
   * @ignore
   */
  circleSelect() {
    this.clear();
    this.getMap().on('click', this._circleClickHandler);
    this.getMap().on('mousemove', this._circleMoveHandler);
  }

  /**
   * 矩形选择
   * @ignore
   */
  rectSelect() {
    this.clear();
    this.getMap().on('click', this._rectClickHandler);
    this.getMap().on('mousemove', this._rectMoveHandler);
  }

  /**
   * 多边形选择
   * @ignore
   */
  polygonSelect() {
    this.polygonPoints = [];
    this.getMap().doubleClickZoom.disable();
    this.clear();
    this.getMap().on('click', this._polygonClickHandler);
    this.getMap().on('mousemove', this._polygonMoveHandler);
    this.getMap().on('dblclick', this._polygonDblclickHandler);
  }

  /**
   * 点点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  pointClickHandler(e) {
    this.offAll();
    this.latestRequestTime = new Date().getTime();
    let xgap = 10, ygap = 10;
    this.log(e);
    let { x, y } = e.point;
    let screenxmin = x - xgap,
      screenxmax = x + xgap,
      screenymin = y - ygap,
      screenymax = y + ygap;
    let minLnglat = this.getMap().unproject([screenxmin, screenymin]),
      maxLnglat = this.getMap().unproject([screenxmax, screenymax]);
    let xmin = minLnglat.lng,
      ymin = minLnglat.lat,
      xmax = maxLnglat.lng,
      ymax = maxLnglat.lat;
    let searchGeometry = turf.polygon([
      [xmin, ymin],
      [xmin, ymax],
      [xmax, ymax],
      [xmax, ymin],
      [xmin, ymin]
    ]);
    this.finish(searchGeometry);
  }

  /**
   * 圆点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  circleClickHandler(e) {
    if (this.firstPoint) {
      this.offAll();
      this.drawCircle([this.firstPoint.lng, this.firstPoint.lat], [e.lngLat.lng, e.lngLat.lat]);
      let circle = this.getMap().getSource(this._sourceId)._data.features[0];
      this.finish(circle.geometry);
      this.firstPoint = null;
    } else {
      this.firstPoint = e.lngLat;
    }
  }

  /**
   * 圆移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  circleMoveHandler(e) {
    if (this.firstPoint) {
      this.tempPoint = e.lngLat;
      this.drawCircle([this.firstPoint.lng, this.firstPoint.lat], [this.tempPoint.lng, this.tempPoint.lat]);
    }
  }

  /**
   * 矩形点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  rectClickHandler(e) {
    if (this.firstPoint) {
      this.offAll();
      this.drawRect([this.firstPoint.lngLat.lng, this.firstPoint.lngLat.lat], [e.lngLat.lng, e.lngLat.lat]);
      let rect = this.getMap().getSource(this._sourceId)._data.features[0];
      let screenGeometry = turf.bboxPolygon([
        ...[this.firstPoint.point.x, this.firstPoint.point.y],
        ...[e.point.x, e.point.y]
      ]);
      this.finish(rect.geometry, screenGeometry);
      this.firstPoint = null;
    } else {
      this.firstPoint = e;
    }
  }

  /**
   * 矩形移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  rectMoveHandler(e) {
    if (this.firstPoint) {
      this.tempPoint = e.lngLat;
      this.drawRect(
        [this.firstPoint.lngLat.lng, this.firstPoint.lngLat.lat],
        [this.tempPoint.lng, this.tempPoint.lat]
      );
    }
  }

  /**
   * 多边形点击事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonClickHandler(e) {
    this.polygonPoints.push(e.lngLat);
    if (this.polygonPoints.length >= 2) {
      this.drawPolygon(this.polygonPoints, e.lngLat);
    }
  }

  /**
   * 多边形移动事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonMoveHandler(e) {
    if (this.polygonPoints && this.polygonPoints.length >= 1) {
      this.drawPolygon(this.polygonPoints, e.lngLat);
    }
  }

  /**
   * 多边形双击事件
   * @param {*} e 事件参数
   * @ignore
   */
  polygonDblclickHandler(e) {
    this.drawPolygon(this.polygonPoints, e.lngLat);
    let polygon = this.getMap().getSource(this._sourceId)._data.features[0];
    this.finish(polygon.geometry);
    this.polygonPoints = [];
    this.offAll();
    setTimeout(() => {
      this.getMap().doubleClickZoom.enable();
    });
  }

  /**
   * 解除事件绑定
   * @ignore
   */
  offAll() {
    // 点
    this.getMap().off('click', this._pointClickHandler);
    // 圆
    this.getMap().off('click', this._circleClickHandler);
    this.getMap().off('mousemove', this._circleMoveHandler);
    // 矩形
    this.getMap().off('click', this._rectClickHandler);
    this.getMap().off('mousemove', this._rectMoveHandler);
    // 多边形
    this.getMap().off('click', this._polygonClickHandler);
    this.getMap().off('mousemove', this._polygonMoveHandler);
    this.getMap().off('dblclick', this._polygonDblclickHandler);
    // 清除鼠标式样
    this.getUtil('CursorUtil').reset();
  }


  /**
   * 绘制选择圆
   * @param {Array} start 圆心
   * @param {Array} end 圆上的点
   * @igonre
   */
  drawCircle(start, end) {
    let distance = turf.distance(turf.point(start), turf.point(end), { units: 'kilometers' });
    let circle = turf.circle(turf.point(start), distance, { units: 'kilometers', steps: 36 });
    circle.properties.sourceType = 'Polygon';
    circle.properties.color = '#ff0000';
    circle.properties.opacity = 0.3;
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([circle]));
  }


  /**
   * 绘制选择矩形
   * @param {Array} start 起点
   * @param {Array} end 终点
   * @igonre
   */
  drawRect(start, end) {
    let rect = turf.bboxPolygon([...start, ...end]);
    rect.properties.sourceType = 'Polygon';
    rect.properties.color = '#ff0000';
    rect.properties.opacity = 0.3;
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([rect]));
  }

  /**
   * 绘制选择多边形
   * @param {*} all 所有点
   * @param {*} last 最新点
   * @igonre
   */
  drawPolygon(all, last) {
    let before = all[all.length - 1];
    if (before.lng !== last.lng || before.lat !== last.lat) {
      if (all.length === 1) {
        let points = all.concat([last]);
        let coords = points.map((item) => [item.lng, item.lat]);
        let lineString = turf.lineString(coords);
        lineString.properties.sourceType = 'LineString';
        lineString.properties.color = '#ff0000';
        lineString.properties.opacity = 1;
        lineString.properties.width = 1;
        this.getMap().getSource(this._sourceId).setData(turf.featureCollection([lineString]));
      } else {
        let points = all.concat([last]).concat([all[0]]);
        let coords = points.map((item) => [item.lng, item.lat]);
        let polygon = turf.polygon([coords]);
        polygon.properties.sourceType = 'Polygon';
        polygon.properties.color = '#ff0000';
        polygon.properties.opacity = 0.3;
        this.getMap().getSource(this._sourceId).setData(turf.featureCollection([polygon]));
      }
    }
  }

  /**
   * 选择图形绘制完成
   * @param {String} shape 选择图形坐标
   */
  finish(geometry, screenGeometry) {
    this.callback(geometry, screenGeometry);
    this.getUtil('CursorUtil').reset();
  }

  /**
   * 清空数据
   * @ignore
   */
  clear() {
    this.getMap().getSource(this._sourceId).setData(turf.featureCollection([]));
    this.getUtil('CursorUtil').reset();
  }
}
export default SelectTool;
